from fastapi import FastAPI, HTTPException, Depends, status
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
from sqlalchemy import create_engine, Column, Integer, String, DateTime, Boolean
from sqlalchemy.orm import sessionmaker, declarative_base
from passlib.context import CryptContext
from jose import JWTError, jwt
from datetime import datetime, timedelta

# 数据库连接信息
SQLALCHEMY_DATABASE_URL = "mysql+pymysql://root:123456@localhost:3306/erp-py?charset=utf8mb4"
engine = create_engine(SQLALCHEMY_DATABASE_URL, echo=True)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base = declarative_base()

# 标准ERP用户表模型
class User(Base):
    __tablename__ = "users"
    id = Column(Integer, primary_key=True, index=True)
    username = Column(String(50), unique=True, index=True, nullable=False)  # 登录名
    password = Column(String(128), nullable=False)  # 加密密码
    real_name = Column(String(50), nullable=True)   # 真实姓名
    email = Column(String(100), unique=True, nullable=True)  # 邮箱
    phone = Column(String(20), nullable=True)       # 手机号
    is_active = Column(Boolean, default=True)       # 是否激活
    role = Column(String(20), default="user")       # 角色（如admin、user等）
    created_at = Column(DateTime, default=datetime.utcnow)  # 创建时间

# 创建所有表
Base.metadata.create_all(bind=engine)

app = FastAPI()

pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
SECRET_KEY = "your_erp_secret_key"  # 请替换为更安全的密钥
ALGORITHM = "HS256"
ACCESS_TOKEN_EXPIRE_MINUTES = 60

oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/erp/login")

def hash_password(password: str):
    return pwd_context.hash(password)

def verify_password(plain_password, hashed_password):
    return pwd_context.verify(plain_password, hashed_password)

def create_access_token(data: dict, expires_delta: timedelta = None):
    to_encode = data.copy()
    expire = datetime.utcnow() + (expires_delta or timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES))
    to_encode.update({"exp": expire})
    return jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)

def get_db():
    db = SessionLocal()
    try:
        yield db
    finally:
        db.close()

def get_current_user(token: str = Depends(oauth2_scheme), db=Depends(get_db)):
    credentials_exception = HTTPException(
        status_code=status.HTTP_401_UNAUTHORIZED,
        detail="无效认证凭据",
        headers={"WWW-Authenticate": "Bearer"},
    )
    try:
        payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
        username: str = payload.get("sub")
        if username is None:
            raise credentials_exception
    except JWTError:
        raise credentials_exception
    user = db.query(User).filter(User.username == username).first()
    if user is None:
        raise credentials_exception
    return user

# 注册接口（标准ERP字段，支持真实姓名、邮箱、手机号）
@app.post("/erp/register")
def erp_register(
    form_data: OAuth2PasswordRequestForm = Depends(),
    real_name: str = "",
    email: str = "",
    phone: str = "",
    db=Depends(get_db)
):
    user = db.query(User).filter(User.username == form_data.username).first()
    if user:
        raise HTTPException(status_code=400, detail="用户名已存在")
    if email:
        email_exist = db.query(User).filter(User.email == email).first()
        if email_exist:
            raise HTTPException(status_code=400, detail="邮箱已存在")
    hashed_pw = hash_password(form_data.password)
    new_user = User(
        username=form_data.username,
        password=hashed_pw,
        real_name=real_name,
        email=email,
        phone=phone
    )
    db.add(new_user)
    db.commit()
    db.refresh(new_user)
    return {"msg": "注册成功", "username": new_user.username}

# 登录接口
@app.post("/erp/login")
def erp_login(form_data: OAuth2PasswordRequestForm = Depends(), db=Depends(get_db)):
    user = db.query(User).filter(User.username == form_data.username).first()
    if not user or not verify_password(form_data.password, user.password):
        raise HTTPException(status_code=401, detail="用户名或密码错误")
    access_token = create_access_token(data={"sub": user.username})
    return {"access_token": access_token, "token_type": "bearer", "username": user.username}

# 获取当前登录用户信息
@app.get("/erp/me")
def erp_me(current_user: User = Depends(get_current_user)):
    return {
        "id": current_user.id,
        "username": current_user.username,
        "real_name": current_user.real_name,
        "email": current_user.email,
        "phone": current_user.phone,
        "role": current_user.role,
        "is_active": current_user.is_active,
        "created_at": current_user.created_at
    }